<!--
 * @author luguoxiang
 * @date 2022/9/17
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <table-container>
    <lg-table :schema="schema" v-bind="tableProps">
      <!-- 工具栏 -->
      <template #toolbar-left>
        <lg-button-list :limit="$ToolBtnLimit" :children="getChildren">
          <slot name="toolbar-left-before"></slot>
          <btn-tool-add @click="openEdit()" />
          <btn-tool-remove @click="remove()" />
          <btn-tool-export @click="exports" />
          <btn-tool-import @click="imports" />
          <slot name="toolbar-left-after"></slot>
          <template #trigger><btn-tool-more /></template>
        </lg-button-list>
      </template>
      <!-- 操作栏 -->
      <template #actionbar="scope">
        <lg-button-list :limit="$RowBtnLimit" :children="getChildren">
          <slot name="actionbar-before" v-bind="scope"></slot>
          <btn-row-view @click="openDetail(scope.row)" />
          <btn-row-update @click="openEdit(scope.row)" />
          <btn-row-remove @click="remove(scope.row.id)" />
          <slot name="actionbar-after" v-bind="scope"></slot>
        </lg-button-list>
      </template>
      <!-- 插槽 -->
      <template v-for="(x, key) in $slots" #[key]="scope">
        <slot :name="key" v-bind="scope"></slot>
      </template>
    </lg-table>
    <detail-container ref="detailRef" v-bind="detailConfig">
      <lg-description ref="descriptionRef" v-loading="detailLoading" :schema="schema" v-bind="descriptionConfig">
        <!-- 插槽 -->
        <template v-for="(x, key) in $slots" #[key]="scope">
          <slot :name="key" v-bind="scope"></slot>
        </template>
      </lg-description>
    </detail-container>
    <edit-container ref="editRef" v-bind="editConfig">
      <lg-form ref="formRef" v-loading="editLoading" :schema="schema" v-bind="formConfig">
        <!-- 插槽 -->
        <template v-for="(x, key) in $slots" #[key]="scope">
          <slot :name="key" v-bind="scope"></slot>
        </template>
      </lg-form>
    </edit-container>
  </table-container>
</template>

<script lang="ts">
export default {
  name: 'PageWrapper',
};
</script>
<script setup lang="ts">
import { ref } from 'vue';
import { DetailContainer, EditContainer, TableContainer, useDetailContainer, useEditContainer } from '@/components';
import {
  IConfigSchema,
  LgDescription,
  LgDescriptionProps,
  LgForm,
  LgFormProps,
  LgTable,
  LgTableProps,
  LgButtonList,
  useTable,
} from '@/soar';

interface Api {
  saveOrUpdate(values: any, isUpdate: boolean): Promise<any>;
  remove(ids: string[]): Promise<any>;
  detail(id: string, params?: any): Promise<any>;
  query(): Promise<any>;
}

interface Props {
  /**
   * 结构配置
   */
  schema: IConfigSchema<unknown>[];
  /**
   * 接口
   */
  api: Api;
  /**
   * 主题标题
   */
  subject: string;
  /**
   * 主键字段
   */
  rowKey?: string;
  /**
   * table配置
   */
  tableProps?: LgTableProps;
  /**
   * 详情配置
   */
  detailProps?: LgDescriptionProps;
  /**
   * 详情容器配置
   */
  detailContainerProps?: any;
  /**
   * 编辑配置
   */
  editProps?: LgFormProps;
  /**
   * 编辑容器配置
   */
  editContainerProps?: any;
}

const props = defineProps<Props>();

function getChildren(slots) {
  slots = slots.default();
  const before = slots[0].children;
  const after = slots[slots.length - 1].children;
  let children = slots.slice(1, slots.length - 1);
  if (before.length) {
    children = before.concat(children);
  }
  if (after.length) {
    return children.concat(after);
  }
  return children;
}

// 列表
const tableContent = useTable<any>({
  api: props.api,
  rowKey: props.rowKey,
  props: props.tableProps,
});
const { remove, exports, imports, reload, selectedKeys, selectedRows, tableProps, tableRef } = tableContent;

// 详情
const detailRef = ref();
const descriptionRef = ref();
const detailContent = useDetailContainer({
  containerProps: props.detailContainerProps,
  containerRef: detailRef,
  header: `${props.subject}详情`,
  getData: (params: any) => props.api.detail(params.id, params),
});
const { containerConfig: detailConfig, descriptionConfig, loading: detailLoading, open: openDetail } = detailContent;

// 表单
const editRef = ref();
const formRef = ref();
const editContent = useEditContainer<any>({
  header: props.subject,
  containerRef: editRef,
  formRef,
  containerProps: props.editContainerProps,
  getData: (params: any) => props.api.detail(params.id),
  onOk: async ({ values, data, isUpdate, changed }) => {
    if (changed) {
      values.id = data.id;
      await props.api.saveOrUpdate(values, isUpdate);
      reload();
    }
  },
});
const { containerConfig: editConfig, formConfig, loading: editLoading, open: openEdit } = editContent;

// 输出
defineExpose({
  openEdit,
  openDetail,
  reload,
  selectedKeys,
  selectedRows,
  tableRef,
  descriptionRef,
  formRef,
  table: tableContent,
  edit: editContent,
  detail: detailContent,
});
</script>
